package cc.rengu.igas.smps.core.packswitch;

import cc.rengu.igas.share.common.util.Base64;
import cc.rengu.igas.smps.common.constant.SmpsTreeNodeConstant;
import cc.rengu.jradp.packetswitch.IncomingPackSwitchImpl;
import cc.rengu.jradp.packetswitch.OutgoingPackSwitchImpl;
import cc.rengu.oltp.utility.util.SHAUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.*;

/**
 * @author wukefan
 * @version 1.0.0
 * @date 2020/10/27 21:18
 */
public class CompMchntPushFromCashClientPackSwitch implements IncomingPackSwitchImpl, OutgoingPackSwitchImpl {
    RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    @Override
    public byte[] beforeInComPackSwitch(byte[] bytes) throws Exception {
        String accessMsg = new String(bytes, "UTF-8");
        rglog.debug("响应信息：<{}>", accessMsg);
        Map<String, String> respparam = new HashMap<>();
        if (!StringUtil.isEmptyOrNull(accessMsg)) {
            respparam.put("rspCd", "00000000");
            respparam.put("rspDc", "消息推送成功！");
        } else {
            respparam.put("rspCd", "ER000096");
            respparam.put("rspDc", "未接收到第三方应答！");
        }
        return JSONObject.toJSONString(respparam).getBytes("UTF-8");
    }

    @Override
    public int afterInComPackSwitch() throws Exception {
        return 0;
    }

    @Override
    public int beforeOutgoPackSwitch() throws Exception {
        return 0;
    }

    @Override
    public byte[] afterOutgoPackSwitch(byte[] bytes) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String signKey = xmlTreeUtil.getXmlTreeStringValue(SmpsTreeNodeConstant.SIGN_KEY);
        String signMethod = xmlTreeUtil.getXmlTreeStringValue(SmpsTreeNodeConstant.SIGN_METHOD);

        String reqParam = new String(bytes);

        String mac = generateMac(reqParam, signKey, signMethod);
        rglog.info("mac = <{}>", mac);

        JSONObject jsonObject = JSON.parseObject(reqParam);
        JSONObject rspDataJson = (JSONObject) jsonObject.get("rspData");
        rspDataJson.put("mac", mac);
        jsonObject.put("rspData", rspDataJson);
        String data = new String(Base64.encode(JSONObject.toJSONString(jsonObject).getBytes("UTF-8")));
        String requestParam = "jsonData=" + data + "&merNo=" + xmlTreeUtil.getXmlTreeStringValue(SmpsTreeNodeConstant.MCHNT_CD);
        requestParam = requestParam.replace("+", "%2B").replaceAll("\\s*|\t|\r|\n", "");
        if (!StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(SmpsTreeNodeConstant.REQ_PARAM))) {
            requestParam = xmlTreeUtil.getXmlTreeStringValue(SmpsTreeNodeConstant.REQ_PARAM).concat("&").concat(requestParam);
        }

        return requestParam.getBytes("UTF-8");
    }


    /* public static void main(String[] args) {
         String reqParam = "{\"rspHead\":{\"bkId\":\"866\",\"rspCd\":\"S000A000\",\"msg\":\"支付成功\"},\"rspData\":{\"orderNo\":\"121315456456\",\"orderAmt\":\"0.12\",\"orderTime\":\"202007201121001\",\"srpFlowNo\":\"21356563123125\",\"payTime\":\"202007201122001\",\"payAccount\":\"62265656565656125\",\"recAccount\":\"1545644564546546\",\"orderTitle\":\"示例\",\"orderDesc\":\"sdajflkajdgkasdl\",\"merchName\":\"866565455\",\"recUserName\":\"sdfds\",\"orderState\":\"90\"}}";
         String signKey = "6D58D9E157526C49A2FEB38BE13A27";
         String signMethod = "SHA1";
         String mac = null;
         try {
             mac = generateMac(reqParam,signKey,signMethod);
         } catch (NoSuchAlgorithmException e) {
             rglog.error(e.getMessage());
         }

         JSONObject jsonObject = JSON.parseObject(reqParam);
         JSONObject rspDataJson = (JSONObject) jsonObject.get("rspData");
         rspDataJson.put("mac",mac);
         jsonObject.put("rspData",rspDataJson);
         System.out.println(JSONObject.toJSONString(jsonObject));
     }
 */
    private String generateMac(String reqParam, String signKey, String signMethod) throws Exception {
        rglog.info("param = <{}>", reqParam);
        //System.out.println("param = <{}>"+reqParam);
        JSONObject jsonObject = JSON.parseObject(reqParam);
        Map<String, String> reqHeadMap = (Map<String, String>) jsonObject.get("rspHead");
        Map<String, String> reqDataMap = (Map<String, String>) jsonObject.get("rspData");
        Map<String, String> resp = new HashMap<>();
        if (!reqHeadMap.isEmpty()) {
            for (Map.Entry<String, String> head : reqHeadMap.entrySet()) {
                resp.put(head.getKey(), head.getValue());
            }
        }
        if (!reqDataMap.isEmpty()) {
            for (Map.Entry<String, String> data : reqDataMap.entrySet()) {
                resp.put(data.getKey(), data.getValue());
            }
        }
        resp.put("macKey", signKey);
        Map<String, Object> params = new HashMap<>();
        params.putAll(resp);
        String signBlock = generateParamStr(params) + "&" + signKey;
        rglog.info("signBlock = <{}>", signBlock);
        return SHAUtil.geneHexrateSignString(signMethod, signBlock);

    }

    /**
     * 生成用于MAC计算的参数字符串。<br>
     *
     * @return 模式为key=value&key=value
     */
    private static String generateParamStr(Map<String, Object> params) {
        // 取所有非空字段内容（除macKey以外），塞入列表

        List<String> paramList = new ArrayList<String>();
        for (String key : params.keySet()) {
            if ("macKey".equals(key) || "mac".equals(key)) {
                continue;
            }
            String val = (String) params.get(key);
            paramList.add(key + "=" + val);
        }
        // 防护
        if (paramList.size() == 0) {
            return null;
        }
        // 对列表进行排序
        Collections.sort(paramList);
        // 以&符分割拼装成字符串
        StringBuilder sb = new StringBuilder();
        sb.append(paramList.get(0));
        for (int i = 1; i < paramList.size(); i++) {
            sb.append("&").append(paramList.get(i));
        }
        return sb.toString();
    }
}
